/*
 * ota.c
 *
 *  Created on: Mar 19, 2024
 *      Author: lye21
 */

#include "ota.h"

void MoveCode(unsigned int des_addr, unsigned int byte_size) {
	uint8_t temp[1024];
	printf("> Start copy......\r\n");
	for (int i = 0; i < byte_size / 1024; i++) {
		BSP_W25Qx_Read(temp, i * 1024, 1024);
//		ReadFlash((src_addr + i * 1024), temp, 1024);
		WriteFlash((des_addr + i * 1024), temp, 1024);
	}
	printf("> Copy sucessfully......\r\n");

}

// EEPROM读取
//int EEPROM_ReadBytes(uint16_t Addr) {
//	uint8_t *wAddr;
//	uint8_t Buffer[50];
//	uint8_t len = 0;
//	int value = 0;
//
//	wAddr = (uint8_t*) (EEPROM_BASE_ADDR + Addr);
//	while (len < 50) {
//		Buffer[len] = *wAddr++;
//		len++;
//	}
//	value = atoi(Buffer);
//	return value;
//}
//
//// EEPORM写入
//void EEPROM_WriteBytes(uint16_t Addr, uint8_t *Buffer, uint16_t Length) {
//	uint8_t *wAddr;
//	wAddr = (uint8_t*) (EEPROM_BASE_ADDR + Addr);
//	DIS_INT
//	FLASH->PEKEYR = PEKEY1;                //unlock
//	FLASH->PEKEYR = PEKEY2;
//	while (FLASH->PECR & FLASH_PECR_PELOCK)
//		;
//	//FLASH->PECR|=FLASH_PECR_FTDW;        //not fast write
//	while (Length--) {
//		*wAddr++ = *Buffer++;
//		while (FLASH->SR & FLASH_SR_BSY)
//			;
//	}
//	FLASH->PECR |= FLASH_PECR_PELOCK;
//	EN_INT
//
//	HAL_Delay(10);
//}

typedef void (*Jump_Fun)(void);
void IAP_ExecuteApp(uint32_t App_Addr) {
	Jump_Fun JumpToApp;
//	printf("%02X\r\n", ((*(__IO uint32_t*) App_Addr) & 0x2FFE0000));
	if (((*(__IO uint32_t*) App_Addr) & 0x2FFE0000) == 0x20000000) //检查栈顶地址是否合法.
			{
		JumpToApp = (Jump_Fun) *(__IO uint32_t*) (App_Addr + 4); //用户代码区第二个字为程序开始地址(复位地址)
		__set_MSP(*(__IO uint32_t*) App_Addr);	//初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
		JumpToApp();	//跳转到APP
	} else {
		printf("There is None APP to jump,ERROR!!!\r\n");
	}
}

unsigned int Read_Start_Mode(void) {
	int mode = 0;
	mode = EEPROM_ReadBytes(EEPROM_OTA_ADDR);
	return mode;
}

void Start_BootLoader(void) {
//	EEPROM_WriteBytes(EEPROM_OTA_ADDR, 0, 1);
//	switch (Read_Start_Mode())									//读取是否启动应用程序
//	{
//	case 0:										//正常启动
//	{
//		printf("> Normal start......\r\n");
//		break;
//	}
//	case 1:										//升级再启动
//	{
//		printf("> Start update......\r\n");
////		MoveCode(Application_1_Addr, Application_Size);
//		printf("> Update sucessfully......\r\n");
//		break;
//	}
//	default:															//启动失败
//	{
//		printf("> Error:%X!!!......\r\n", Read_Start_Mode());
//		return;
//	}
//	}
//	/* 跳转到应用程序 */
	printf("> Start up......\r\n\r\n");
	__disable_irq();  //很重要！经测试STM32F4必要！  貌似F105也需要   L431 裸机 却不需要  RTOS需要

	IAP_ExecuteApp(Application_1_Addr);
}




